﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using haptic.src.engine;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;
using haptic.src.engine.core;

namespace haptic.src.components
{
    [Serializable]
    public class cPlayer : cCharacter
    {
        #region Constructors
        public cPlayer(){}
        public cPlayer(Entity oOwner) : base(oOwner) { }
        #endregion

        #region Load
        public override Result Load(Scene oScene, Microsoft.Xna.Framework.Content.ContentManager oContent)
        {
            m_oGroundCollisionSound = oContent.Load<SoundEffect>(@"Sounds/Fx/2063_TwistedLemon_MATTEL_TOM10");
            m_oJumpSound = oContent.Load<SoundEffect>(@"Sounds/Fx/2063_TwistedLemon_MATTEL_TOM10");

            oScene.RegisterPlayer(m_oEntity);

            return base.Load(oScene, oContent);
        }
        public override void Unload(Scene oScene)
        {
            oScene.UnregisterPlayer(m_oEntity);
        }
        #endregion

        #region Update
        private void UpdateInput(GameTime oTime)
        {
            Debug.Assert(m_oPhysics != null);
            float fDt = (float)oTime.ElapsedGameTime.TotalSeconds;
            KeyboardState oKeyboard = Keyboard.GetState();

            bool bOrderRequested = false;
            float fHorizontalSpeed = F_HORIZONTAL_AIR_ACCELERATION;
            if (m_oPhysics.bIsOnGround)
            {
                fHorizontalSpeed = F_HORIZONTAL_GROUND_MOVE_SPEED;
                if (oKeyboard.IsKeyDown(Keys.Space))
                {
                    SetOrder(Order.E_JUMP);
                    bOrderRequested = true;
                    if (m_oJumpSound != null)
                        m_oJumpSound.Play(1.0f, 1.0f, 0.0f, false);
                }
                else if (m_oPhysics.eCollisionEvent == cPhysics.CollisionEvent.E_START_TOUCH)
                {
                    if (m_eState == State.E_FALLING && m_oGroundCollisionSound != null)
                    {
                        /*float fVolume = Math.Abs(m_oPhysics.m_vVelocity.Y) / 50.0f;
                        if (fVolume > 1.0f)
                            fVolume = 1.0f;*/
                        m_oGroundCollisionSound.Play(/*fVolume*/);
                    }
                }
            }

            if (oKeyboard.IsKeyDown(Keys.LeftShift))
            {
                fHorizontalSpeed *= 0.5f;
            }
            
            if (oKeyboard.IsKeyDown(Keys.Left) || oKeyboard.IsKeyDown(Keys.Q))
            {
                SetOrder(Order.E_RUN);
                bOrderRequested = true;
                if (m_oPhysics.bIsOnGround)
                    m_oPhysics.m_vVelocity.X = -fHorizontalSpeed;
                else if (m_oPhysics.m_vVelocity.X > -F_HORIZONTAL_AIR_MAX_SPEED)
                {
                    m_oPhysics.m_vVelocity.X -= fHorizontalSpeed * fDt;
                    if (m_oPhysics.m_vVelocity.X < -F_HORIZONTAL_AIR_MAX_SPEED)
                        m_oPhysics.m_vVelocity.X = -F_HORIZONTAL_AIR_MAX_SPEED;
                }
            }
            if (oKeyboard.IsKeyDown(Keys.Right) || oKeyboard.IsKeyDown(Keys.D))
            {
                SetOrder(Order.E_RUN);
                bOrderRequested = true;
                if (m_oPhysics.bIsOnGround)
                    m_oPhysics.m_vVelocity.X = fHorizontalSpeed;
                else if (m_oPhysics.m_vVelocity.X < F_HORIZONTAL_AIR_MAX_SPEED)
                {
                    m_oPhysics.m_vVelocity.X += fHorizontalSpeed * fDt;
                    if (m_oPhysics.m_vVelocity.X > F_HORIZONTAL_AIR_MAX_SPEED)
                        m_oPhysics.m_vVelocity.X = F_HORIZONTAL_AIR_MAX_SPEED;
                }
            }
            if (!bOrderRequested)
                SetOrder(Order.E_IDLE);
        }
        public override void Update(GameTime oTime)
        {
            UpdateInput(oTime);
            base.Update(oTime);
        }
        public override void PostUpdate(GameTime oTime)
        {
            base.PostUpdate(oTime);
        }
        #endregion

        #region Attributes
        private const float F_HORIZONTAL_AIR_MAX_SPEED = 300.0f;
        private const float F_HORIZONTAL_AIR_ACCELERATION = 1000.0f;
        private const float F_HORIZONTAL_GROUND_MOVE_SPEED = 300.0f;
        private SoundEffect m_oGroundCollisionSound;
        private SoundEffect m_oJumpSound;
        #endregion
    }
}
